package com.google.rui.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.util.Log;

public class CrashHandler implements UncaughtExceptionHandler {
	/** Debug Log tag */
	public static final String TAG = "CrashHandler";

	/** 系统默认的UncaughtException处理类 */
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	/** CrashHandler实例 */
	private static CrashHandler INSTANCE;

	/** 错误报告文件的扩展名 */
	private static final String CRASH_REPORTER_EXTENSION = ".txt";

	private static final String CRASH_REPORTER_DIR = "/sdcard/StrongSoft/DonjonAndroidClient/log";

	/** 保证只有一个CrashHandler实例 */
	private CrashHandler() {
	}

	/** 获取CrashHandler实例 ,单例模式 */
	public static CrashHandler getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new CrashHandler();
		}
		return INSTANCE;
	}

	/**
	 * 初始化,获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
	 * 
	 * @param ctx
	 */
	public void init() {
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);

		File destDir = new File(CRASH_REPORTER_DIR);
		if (!destDir.exists()) {
			destDir.mkdirs();
		}
	}

	/**
	 * 当UncaughtException发生时会转入该函数来处理
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		handleException(ex);
		if (mDefaultHandler != null)
			mDefaultHandler.uncaughtException(thread, ex);
	}

	/**
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
	 * 
	 * @param ex
	 */
	private void handleException(Throwable ex) {
		if (ex == null) {
			return;
		}
		saveCrashInfoToFile(ex);
	}

	/**
	 * 保存错误信息到文件中
	 * 
	 * @param ex
	 * @return
	 */
	private void saveCrashInfoToFile(Throwable ex) {
		Writer info = new StringWriter();
		PrintWriter printWriter = new PrintWriter(info);
		ex.printStackTrace(printWriter);
		Throwable cause = ex.getCause();
		while (cause != null) {
			cause.printStackTrace(printWriter);
			cause = cause.getCause();
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date1 = new Date(System.currentTimeMillis());
		
		String result = sdf.format(date1) + "\n" + info.toString() + "\r\n" + "\r\n";
		printWriter.close();
		try {
			SimpleDateFormat sfd = new SimpleDateFormat("yyyyMMdd");
			Date date = new Date(System.currentTimeMillis());
			String fileName = CRASH_REPORTER_DIR + "/crash-" + sfd.format(date)
					+ CRASH_REPORTER_EXTENSION;
			BufferedWriter mWriter = new BufferedWriter(new FileWriter(
					fileName, true));
			mWriter.write(result);
			mWriter.flush();
			mWriter.close();
		} catch (IOException e) {
			Log.e(TAG, "an error occured while writing report file...", e);
		}
	}
}
